import type {
  CreateCrudOptionsProps,
  CreateCrudOptionsRet,
  InfoReq,
  ScopeContext,
  UserPageRes,
} from '@fast-crud/fast-crud';

import type { FormRulesExt } from '#/api';
import type { DefDictModel } from '#/api/devOperation/system/model/defDictModel';

import { ref } from 'vue';

import { useAccess } from '@vben/access';

import { RuleType } from '#/api';
import { DefDictItemApi } from '#/api/devOperation/system/defDictItem';
import { IconPicker } from '#/components/form';
import { PermCode } from '#/enums/perm';
import { useMessage } from '#/hooks/web/useMessage';
import { $t } from '#/locales';
import {
  deleteButton,
  indexColumn,
  STATE_CONSTANT_DICT,
  transformQuery,
} from '#/plugins/fast-crud/common';

import I18nJson from '../I18nJson.vue';

const { hasPermission } = useAccess();
const permCode = PermCode.devOperation.system.dict;

export function createCrudOptions(
  props: CreateCrudOptionsProps<DefDictModel.DefDictResultVO, any>,
): CreateCrudOptionsRet<DefDictModel.DefDictResultVO> {
  const selectedRowKeys = ref<string[]>([]);
  const { createMessage } = useMessage();

  const infoRequest = async (ctx: InfoReq): Promise<UserPageRes> => {
    const { row } = ctx;
    const parentId = props.context.parentIdRef.value;
    if (!parentId) {
      createMessage.warning('请先选择字典');
      throw new Error('请先选择字典');
    }
    const parent = await DefDictItemApi.get(parentId);
    if (row === undefined) {
      const node = {} as InfoReq;
      node.parentId = parent.id;
      node.parentKey = parent.key;
      node.parentName = parent.name;
      return node;
    }
    row.parentId = parent.id;
    row.parentKey = parent.key;
    row.parentName = parent.name;
    return row;
  };

  return {
    crudOptions: {
      id: 'def_dict_item',
      request: {
        pageRequest: DefDictItemApi.pageRequest,
        addRequest: DefDictItemApi.addRequest,
        editRequest: DefDictItemApi.editRequest,
        delRequest: DefDictItemApi.delRequest,
        infoRequest,
        transformQuery: (query) => {
          const tq = transformQuery(query);
          tq.model.parentId = props.context.parentIdRef.value;
          tq.sort = 'sortValue';
          tq.order = 'ascend';
          return tq;
        },
      },
      actionbar: {
        buttons: {
          add: { show: hasPermission(permCode.addItem) },
          ...deleteButton({
            crudExpose: props.crudExpose,
            selectedRowKeys,
            role: permCode.deleteItem,
            removeFn: DefDictItemApi.removeFn,
          }),
        },
      },
      table: {
        striped: true,
        rowKey: 'id',
        rowSelection: {
          type: 'checkbox',
          selectedRowKeys,
          onChange: (changed: string[]) => {
            selectedRowKeys.value = changed;
          },
        },
      },
      rowHandle: {
        width: 150,
        buttons: {
          view: { show: false },
          edit: { show: hasPermission(permCode.editItem) },
          remove: { show: hasPermission(permCode.deleteItem) },
          copy: { show: hasPermission(permCode.addItem) },
        },
      },
      columns: {
        ...indexColumn(props.crudExpose),
        parentId: {
          title: $t('devOperation.system.defDictItem.parentId'),
          type: 'text',
          form: { show: false },
          column: { show: false },
        },
        parentKey: {
          title: $t('devOperation.system.defDictItem.parentKey'),
          type: 'text',
          form: { component: { disabled: true } },
          column: { show: false },
        },
        parentName: {
          title: $t('devOperation.system.defDictItem.parentName'),
          type: 'text',
          form: { component: { disabled: true } },
          column: { show: false },
        },
        key: {
          title: $t('devOperation.system.defDictItem.key'),
          type: 'text',
          search: { show: true },
        },
        name: {
          title: $t('devOperation.system.defDictItem.name'),
          type: 'text',
          search: { show: true },
        },
        state: {
          title: $t('devOperation.system.defDictItem.state'),
          type: 'dict-radio',
          dict: STATE_CONSTANT_DICT,
          search: { show: true, component: { mode: 'multiple' } },
          addForm: { value: true },
        },
        remark: {
          title: $t('devOperation.system.defDictItem.remark'),
          type: 'textarea',
          column: { show: false },
        },
        sortValue: {
          title: $t('devOperation.system.defDictItem.sortValue'),
          type: 'number',
          column: { show: false },
        },
        icon: {
          title: $t('devOperation.system.defDictItem.icon'),
          type: 'text',
          form: {
            render: (scope: ScopeContext) => {
              return <IconPicker v-model:value={scope.form.icon} />;
            },
          },
          column: { show: false },
        },
        cssStyle: {
          title: $t('devOperation.system.defDictItem.cssStyle'),
          type: 'text',
          column: { show: false },
        },
        cssClass: {
          title: $t('devOperation.system.defDictItem.cssClass'),
          type: 'text',
          column: { show: false },
        },
        propType: {
          title: $t('devOperation.system.defDictItem.propType'),
          type: 'text',
          column: { show: false },
        },
        i18nJson: {
          title: $t('devOperation.system.defDictItem.i18nJson'),
          type: 'text',
          form: {
            col: { span: 12 },
            component: {
              name: I18nJson,
              vModel: 'value',
            },
          },
          column: { show: false },
          viewForm: { ignoreUseCellComponent: true },
        },
      },
    },
  };
}

export const frontRules = {
  addForm: {
    rules: (): FormRulesExt => {
      return {
        key: {
          type: RuleType.and,
          rules: [
            {
              trigger: 'blur',
              type: 'string',
              message: '标识重复',
              asyncValidator: async (_, value: string, callback) => {
                /* if (value) {
                  const { getFormData } = crudExpose;
                    if (
                     await DefDictItemApi.check(value, getFormData().parentId)
                   ) {
                     return callback('标识重复');
                   }
                }*/
                return callback();
              },
            },
          ],
        },
      };
    },
  },
  editForm: {
    rules: (): FormRulesExt => {
      return {
        key: {
          type: RuleType.and,
        },
      };
    },
  },
};
